package ks.server.controllers.commands.admin;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URL;
import java.sql.Time;
import java.util.Calendar;
import java.util.Date;

import ks.framework.common.Message;
import ks.framework.communicator.Communicator;
import ks.framework.interfaces.IProcessMessage;
import ks.managers.game.GameManager;
import ks.managers.icon.Icon;
import ks.managers.icon.IconManager;
import ks.managers.plugin.Plugin;
import ks.managers.plugin.PluginManager;
import ks.managers.table.Table;
import ks.managers.table.TableManager;
import ks.managers.user.User;
import ks.server.ipc.Listener;
import ks.server.persist.PersistentIconManager;
import ks.server.persist.PersistentPluginManager;
import ks.server.persist.PersistentUserManager;
import ks.server.ServerContext;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * Process command to generate a report.
 */
public class ReportController implements IProcessMessage {

	/** Primary agent to whom we can communicate our messages. */
	Communicator com;
	
	public ReportController (Communicator com) {
		this.com = com;
	}
	
	/**
	 * Process the message
	 * 
	 * @param m The message to process.
	 * @return A boolean value.
	 */
	@SuppressWarnings("deprecation")
	public boolean process(Message m) {
		PersistentUserManager um = ServerContext.getUserManager();
		TableManager tm = ServerContext.getTableManager();
		//GameManager gm = ServerContext.getGameManager();
		PersistentIconManager im = ServerContext.getIconManager();
		PluginManager pm = ServerContext.getPluginManager();
		
		Date d = Calendar.getInstance().getTime();
		
		String today = d.getYear() + "-" + d.getMonth() + "-" + d.getDay() + " " + d.getHours() + ":" + d.getMinutes();
		String today2 = d.getYear() + "-" + d.getMonth() + "-" + d.getDay() + "_" + d.getHours() + "-" + d.getMinutes();
		
		try {
			File file = new File("Reports\\report_" + today2 + ".html");
			FileOutputStream fout = new FileOutputStream(file);
			DataOutputStream dout = new DataOutputStream(fout);
			
			String admin, blocked, online, username, icon;
			int rating, won, lost, played;
			Date lastLoginDate;
			String lastLogin;
			
			dout.writeChars("<html>");
			dout.writeChars("<head>");
			dout.writeChars("<title>KombatSolitaire Server Report " + today + "</title>");
			dout.writeChars("</head>");
			dout.writeChars("<body>");
			dout.writeChars("<h1>KombatSolitaire Server Report " + today + "</h1>");
			dout.writeChars("<br/>");
			dout.writeChars("<h2>Users</h2>");
			dout.writeChars("<table class=\"users\">");
			dout.writeChars("<tr><td>Admin</td><td>Blocked</td><td>Online</td><td>Username</td><td>Rating</td><td>Games Won</td><td>Games Lost</td><td>Games Played</td><td>Icon Name</td><td>Last Login</td></tr>");
			for(User u : um.getUserList()) {
				if (u.isAdmin())
					admin = "y";
				else
					admin = "n";
				
				if (u.isBlocked())
					blocked = "y";
				else
					blocked = "n";
				
				if (com.getOnlineUsers().contains(u.getName()))
					online = "y";
				else
					online = "n";
				
				username = u.getName();
				icon = u.getIconName();
				rating = u.getRating();
				won = u.getGamesWon();
				lost = u.getGamesLost();
				played = u.getGamesPlayed();
				
				lastLoginDate = new Date(u.getLastLogin());
				lastLogin = lastLoginDate.getYear() + "-" + lastLoginDate.getMonth() + "-" + lastLoginDate.getDay() + " " + lastLoginDate.getHours() + ":" + lastLoginDate.getMinutes();
				
				dout.writeChars("<tr><td>" + admin + "</td>");
				dout.writeChars("<td>" + blocked + "</td>");
				dout.writeChars("<td>" + online + "</td>");
				dout.writeChars("<td>" + username + "</td>");
				dout.writeChars("<td>" + rating + "</td>");
				dout.writeChars("<td>" + won + "</td>");
				dout.writeChars("<td>" + lost + "</td>");
				dout.writeChars("<td>" + played + "</td>");
				dout.writeChars("<td>" + icon + "</td>");
				dout.writeChars("<td>" + lastLogin + "</td></tr>");
			}
			dout.writeChars("</table>");
			dout.writeChars("<br/>");
			
			/*
			 *  (c) status of current tables; (d) information about the games that are in progress (possibly even who is winning at the moment); (e) icon information, possibly showing these icons via IMG tags in the HTML; (f) Plugin information.Be creative. Be comprehensive. Be real.
			 */
			dout.writeChars("<h2>Table Status</h2>");
			dout.writeChars("<table class=\"tables\">");
			dout.writeChars("<tr><td>ID</td><td>Open</td><td>Undo</td><td>Newhand</td><td>Time</td><td>Plugin</td><td>Moderator</td></tr>");
			
			int tableNum, timeNum;
			String open, undo, newhand, plugin, moderator;
			for (Table table : tm.getAllTables()) {
				if (false)
					open = "y";
				else
					open = "n";
				if (false)
					undo = "y";
				else
					undo = "n";
				if (false)
					newhand = "y";
				else
					newhand = "n";
				
				tableNum = table.getId();
				timeNum = -1;
				plugin = "unknown";
				moderator = table.getModerator();
				
				dout.writeChars("<tr><td>" + tableNum + "</td>");
				dout.writeChars("<td>" + open + "</td>");
				dout.writeChars("<td>" + undo + "</td>");
				dout.writeChars("<td>" + newhand + "</td>");
				dout.writeChars("<td>" + timeNum + "</td>");
				dout.writeChars("<td>" + plugin + "</td>");
				dout.writeChars("<td>" + moderator + "</td></tr>");
				
				for (String player : table.getPlayers()) {
					dout.writeChars("<tr><td/><td colspan=4>" + player + "</td><td/><td/></tr>");
				}
			}
			dout.writeChars("</table>");
			dout.writeChars("<br/>");
			
			dout.writeChars("<h2>Games In Progress</h2>");
			dout.writeChars("<p>To be implemented</p>");
			dout.writeChars("<br/>");
			
			dout.writeChars("<h2>Icon Information</h2>");
			dout.writeChars("<table>");
			dout.writeChars("<tr><td></td><td>Name</td><td>URI</td></tr>");
			
			String iconname, iconLoc;
			
			for (Icon icon2 : im.getList()) {
				iconname = icon2.name;
				iconLoc = icon2.location.toString();
				
				dout.writeChars("<tr><td><img src=\"" + iconLoc + "\"/></td>");
				dout.writeChars("<td>" + iconname + "</td>");
				dout.writeChars("<td>" + iconLoc + "</td></tr>");
			}
			dout.writeChars("</table>");
			dout.writeChars("<br/>");
			
			dout.writeChars("<h2>Plugin Information</h2>");
			dout.writeChars("<table>");
			dout.writeChars("<tr><td>Suspended</td><td>Name</td><td>Wins</td><td>Losses</td><td>Date</td></tr>");
			
			String suspended, pluginName, plugindate;
			Date pluginDate;
			int wins, losses;
			
			for (Plugin plugin2 : pm.getList()) {
				if (plugin2.getSuspended())
					suspended = "y";
				else
					suspended = "n";
				
				pluginName = plugin2.getName();
				wins = plugin2.getWins();
				losses = plugin2.getLosses();
				plugindate = plugin2.getDate();
				
				dout.writeChars("<tr><td>" + suspended + "</td>");
				dout.writeChars("<td>" + pluginName + "</td>");
				dout.writeChars("<td>" + wins + "</td>");
				dout.writeChars("<td>" + losses + "</td>");
				dout.writeChars("<td>" + plugindate + "</td></tr>");
			}
			dout.writeChars("</table>");
			dout.writeChars("<br/>");
			
			dout.writeChars("</body>");
			dout.writeChars("</html>");
			
			dout.close();
			fout.close();
			
		} catch (Exception e) {
			e.printStackTrace();
			Listener.nack(m, 4, "[ReportController] file write failed");
			return false;
		}
		
		Listener.ack(m, "[ReportController] file write success");
		
		return true;
	}
}
